home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / ltick03 / tick.c < prev    next >
C/C++ Source or Header  |  1993-06-09  |  17KB  |  751 lines

  1. /*
  2.  *    LazyTick main module
  3.  *    (LazyTick Project)
  4.  *   
  5.  *    Public Domain: may be copied and sold freely
  6.  */
  7.  
  8. #include    <stdio.h>
  9. #include    <stdlib.h>
  10. #include    <time.h>
  11. #include    <ctype.h>
  12. #include    <string.h>
  13. #include    <stdarg.h>
  14.  
  15. #include    <dirent.h>
  16. #include    <sys/types.h>
  17. #include    <sys/stat.h>
  18.  
  19. #include    "qbbs.h"
  20. #include    "tick.h"
  21. #include     "misc.h"
  22. #include    "config.h"
  23. #include     "announce.h"
  24. #include    "crc32.h"
  25.  
  26. #ifdef LATTICE /* for atari Lattice C 5 */
  27. unsigned long _STACK=16000;
  28. #endif
  29.  
  30. void process_tic(char *, char *,char *, char *);
  31. void send_tic(BTICFILE *,int,int,int,int);
  32.  
  33. #define timenix(a) time(a)
  34.  
  35. /* main */
  36.  
  37. int main(int argc, char **argv)
  38. {
  39.     char net[BBSSTR];
  40.     char tickfile[BBSSTR];
  41.     int received=0;
  42.     BTCKANN *tica;
  43.     ECHOLIST *ticalist;
  44.     DIR *dir;
  45.     struct dirent *mydesc;
  46.  
  47.     printf("%s version %s (compiled on %s)\n",LAZYNAME,LAZYVERS,__DATE__);
  48.     printf("A Public Domain Program. May be copied and sold freely.\n\n");
  49.  
  50.     /* init */
  51.     open_config();
  52.     
  53.     /* mode == debug ? */
  54.     if(argc==2 && !stricmp(argv[1],"debug"))
  55.     {
  56.         debug_config();
  57.         if(open_areas(FAREASFILE)==BBSOK)
  58.         {
  59.             debug_areas();
  60.             close_areas();
  61.         }
  62.     }
  63.     else if(argc==5 && !stricmp(argv[1],"hatch")) /* mode == hatch */
  64.     {
  65.         logline(0,"Loading file area configuration");
  66.         if(open_areas(FAREASFILE)==BBSFAIL)
  67.             return 1;
  68.         logline(1,"Hatching %s to %s (%s)",argv[2],argv[3],argv[4]);
  69.         process_tic(NULL,argv[2],argv[3],argv[4]);
  70.         received++;
  71.         close_areas();
  72.     }
  73.     else if(argc>1)
  74.     {
  75.         printf("Usage: ltick                            (process incoming .tic files)\n"
  76.                "       ltick debug                      (display config file parsing)\n"
  77.                "       ltick hatch <file> <area> <desc> (send local file to network\n\n");
  78.     }
  79.     else
  80.     { /* incoming tics */
  81.         logline(0,"Loading file area configuration");
  82.         if(open_areas(FAREASFILE)==BBSFAIL)
  83.             return 1;
  84.  
  85.         /* process incoming TICs */
  86.         strcpy(net,get_inbound());
  87.  
  88.         dir=opendir(net);
  89.         if(dir)
  90.         {
  91.             while((mydesc=readdir(dir))!=NULL)
  92.             {
  93.                 if(!strendcmp(mydesc->d_name,".tic"))
  94.                 {
  95.                     strcpy(tickfile,net);
  96.                     strcat(tickfile,mydesc->d_name);
  97.                     logline(1,"Processing %s",tickfile);
  98.                     process_tic(tickfile,NULL,NULL,NULL);
  99.                     received++;
  100.                 }
  101.             }
  102.             closedir(dir);
  103.         }
  104.         else
  105.             logline(2,"Can't open dir %s",net);
  106.         close_areas(); /* close fareas.bbs */
  107.     }
  108.     
  109.     /* do announces */    
  110.     if(received)
  111.     {
  112.         if(open_areas(AREASFILE)==BBSOK)
  113.         {
  114.             tica=get_announce();
  115.             while(tica)
  116.             {
  117.                 ticalist=get_area(tica->area);
  118.                 if(ticalist)
  119.                 {
  120.                     if(process_announce(tica->group,ticalist->file,
  121.                             tica->footer[0] ? tica->footer : NULL)==BBSOK)
  122.                         logline(1,"Announced %s to %s",tica->group,tica->area);
  123.                     
  124.                 }
  125.                 else
  126.                     logline(3,"Can't find %s in areas.bbs",tica->area);
  127.                 tica=tica->next;
  128.             }
  129.             close_areas();
  130.         }
  131.         else
  132.             logline(3,"Can't open areas.bbs");
  133.     }
  134.     else
  135.         logline(1,"No inbound activity");
  136.     
  137.     /* close */
  138.     close_config();
  139.     return 0;
  140. }
  141.  
  142. /* process tick file or hatch */
  143.  
  144. void process_tic(char *tickfile, char *hatchfile, char *hatcharea, char *hatchdesc)
  145. {
  146.     BTICFILE *ctic;
  147.     FILE *tickf;
  148.     FILE *descf;
  149.     char desctmp[BBSSTR];    
  150.     char buffer[BBSSTR];
  151.     char shadowpass[BBSSTR];
  152.     ECHOLIST *mylist;
  153.     FIDONODE *mynode;
  154.     struct stat mystat;
  155.     char *ptr;
  156.     int fd_area=0,fd_file=0,fd_desc=0,fd_from=0,fd_origin=0;
  157.     int fd_crc=0,fd_pw=0;
  158.     int badtick=0;
  159.     int seen_flag=0,i;
  160.     
  161.     ctic=malloc(sizeof(struct _ticfile));
  162.     if(!ctic)
  163.     {
  164.         logline(5,"Malloc error for tic structure");
  165.         the_end(242);
  166.     }
  167.  
  168.     ctic->area[0]=0;
  169.     ctic->file[0]=0;
  170.     ctic->desc[0]=0;
  171.     ctic->password[0]=0;
  172.     ctic->crc=0;
  173.     ctic->size=0;
  174.     ctic->from.zone=ctic->from.net=ctic->from.node=ctic->from.point=0;
  175.     ctic->origin.zone=ctic->origin.net=ctic->origin.node=ctic->origin.point=0;
  176.     
  177.     ctic->pass_nb=0;
  178.     ctic->seenby_nb=0;
  179.  
  180.     if(tickfile)
  181.     { /* process .tic file */
  182.         /* load tickfile */
  183.         tickf=fopen(tickfile,"r");
  184.         if(tickf)
  185.         {
  186.             while(fticgets(buffer,BBSSTR-2,tickf)!=NULL)
  187.             {
  188.                 strcln(buffer,-1);
  189.             
  190.                 /* mandatory fields */
  191.                 if(!strticcmp(buffer,"area"))
  192.                 {
  193.                     ptr=nextstrtic(buffer);
  194.                     if(ptr)
  195.                     {
  196.                         strcpy(ctic->area,ptr);
  197.                         fd_area++;
  198.                     }
  199.                 }
  200.                 else if(!strticcmp(buffer,"file"))
  201.                 {
  202.                     ptr=nextstrtic(buffer);
  203.                     if(ptr)
  204.                     {
  205.                         strcpy(ctic->file,ptr);
  206.                         fd_file++;
  207.                     }
  208.                 }
  209.                 else if(!strticcmp(buffer,"desc"))
  210.                 {
  211.                     ptr=nextstrtic(buffer);
  212.                     if(ptr)
  213.                     {
  214.                         strcpy(ctic->desc,ptr);
  215.                         fd_desc++;
  216.                     }
  217.                 }
  218.                 else if(!strticcmp(buffer,"origin"))
  219.                 {
  220.                     ptr=nextstrtic(buffer);
  221.                     if(ptr)
  222.                     {
  223.                         if(getaddress(ptr,&ctic->origin.zone,&ctic->origin.net,
  224.                             &ctic->origin.node,&ctic->origin.point))
  225.                         {
  226.                             fd_origin++;
  227.                         }
  228.                     }
  229.                 }
  230.                 else if(!strticcmp(buffer,"from"))
  231.                 {
  232.                     ptr=nextstrtic(buffer);
  233.                     if(ptr)
  234.                     {
  235.                         if(getaddress(ptr,&ctic->from.zone,&ctic->from.net,
  236.                             &ctic->from.node,&ctic->from.point))
  237.                         {
  238.                             fd_from++;
  239.                         }
  240.                     }
  241.                 }
  242.                 /* optional fields */
  243.                 else if(!strticcmp(buffer,"seenby"))
  244.                 {
  245.                     ptr=nextstrtic(buffer);
  246.                     if(ptr)
  247.                     {
  248.                         if(ctic->seenby_nb<MAXSEEN)
  249.                         {
  250.                             if(getaddress(ptr,&(ctic->seenby[ctic->seenby_nb].zone),
  251.                                 &(ctic->seenby[ctic->seenby_nb].net),
  252.                                 &(ctic->seenby[ctic->seenby_nb].node),
  253.                                 &(ctic->seenby[ctic->seenby_nb].point)));
  254.                             {
  255.                                 ctic->seenby[ctic->seenby_nb].position=0;
  256.                                 ctic->seenby_nb++;
  257.                             }
  258.                         }
  259.                     }
  260.                 }
  261.                 else if(!strticcmp(buffer,"crc"))
  262.                 {
  263.                     ptr=nextstrtic(buffer);
  264.                     if(ptr)
  265.                     {
  266.                         ctic->crc=xtol(ptr);
  267.                         fd_crc++;
  268.                     }
  269.                 }
  270.                 else if(!strticcmp(buffer,"size"))
  271.                 {
  272.                     ptr=nextstrtic(buffer);
  273.                     if(ptr)
  274.                     {
  275.                         ctic->size=(unsigned long) atol(ptr);
  276.                     }
  277.                 }
  278.                 else if(!strticcmp(buffer,"pw"))
  279.                 {
  280.                     ptr=nextstrtic(buffer);
  281.                     if(ptr)
  282.                     {
  283.                         strcpy(ctic->password,ptr);
  284.                         fd_pw++;
  285.                     }    
  286.                 }
  287.                 else if(!strticcmp(buffer,"log"))
  288.                 {
  289.                     ptr=nextstrtic(buffer);
  290.                     if(ptr)
  291.                         logline(1,"Message in TIC: %s",ptr);
  292.                 }
  293.                 else if(!strticcmp(buffer,"created"))
  294.                     ; /* skip */
  295.                 /* passthru fields */
  296.                 else if(!strticcmp(buffer,"path")
  297.                     || !strticcmp(buffer,"app")
  298.                     || !strticcmp(buffer,"release")
  299.                     || !strticcmp(buffer,"replaces")
  300.                     || !strticcmp(buffer,"magic")
  301.                     || !strticcmp(buffer,"date"))
  302.                 {
  303.                     if(ctic->pass_nb<MAXPASSNB)
  304.                     {
  305.                         if(strlen(buffer)>PASSLEN-2)
  306.                             buffer[PASSLEN-1]=0;
  307.                         strcpy(ctic->pass[ctic->pass_nb],buffer);
  308.                         ctic->pass_nb++;
  309.                     }
  310.                 }
  311.                 else
  312.                 {
  313.                     logline(2,"Unknown field: %s",buffer);
  314.                     /* pass unknow line thru, as per fsc-0028 */
  315.                     if(ctic->pass_nb<MAXPASSNB)
  316.                     {
  317.                         if(strlen(buffer)>PASSLEN-2)
  318.                             buffer[PASSLEN-1]=0;
  319.                         strcpy(ctic->pass[ctic->pass_nb],buffer);
  320.                         ctic->pass_nb++;
  321.                     }
  322.                 }    
  323.             }
  324.         
  325.             fclose(tickf);
  326.             
  327.             /* create filepath */
  328.             strcpy(ctic->filepath,get_inbound());
  329.             strcat(ctic->filepath,ctic->file);
  330.         }
  331.         else
  332.             logline(4,"Can't open tickfile %s",tickfile);
  333.     }
  334.     else /* hatch */
  335.     {
  336.         int k;
  337.         
  338.         mylist=get_area(hatcharea);
  339.         if(!mylist)
  340.         {
  341.             logline(2,"Area %s doesn't exist",hatcharea);
  342.         }
  343.         else
  344.         {
  345.             /* reset size */
  346.             ctic->size=0;
  347.             
  348.             /* copy area */
  349.             strcpy(ctic->area,hatcharea);
  350.             fd_area++;
  351.         
  352.             /* copy filename part */
  353.             k=strlen(hatchfile);
  354.             while(k>0 && hatchfile[k]!=SYSSEPAR)
  355.                 k--;
  356.             if(k>0)
  357.                 strcpy(ctic->file,hatchfile+k+1);
  358.             else
  359.                 strcpy(ctic->file,hatchfile);
  360.             fd_file++;
  361.             
  362.             /* description */
  363.             strcpy(ctic->desc,hatchdesc);
  364.             fd_desc++;
  365.         
  366.             /* actual filename */
  367.             strcpy(ctic->filepath,hatchfile);
  368.             
  369.             /* origin/from */
  370.             if(mylist->firstnode)
  371.             {
  372.                 get_ouraddress(&(ctic->from),
  373.                     (mylist->firstnode)->zone,
  374.                     (mylist->firstnode)->net,
  375.                     (mylist->firstnode)->node,
  376.                     (mylist->firstnode)->point);
  377.                 fd_from++;
  378.                 get_ouraddress(&(ctic->origin),
  379.                     (mylist->firstnode)->zone,
  380.                     (mylist->firstnode)->net,
  381.                     (mylist->firstnode)->node,
  382.                     (mylist->firstnode)->point);
  383.                 fd_origin++;
  384.             }
  385.             else
  386.             {
  387.                 get_ouraddress(&ctic->from,0,0,0,0);
  388.                 fd_from++;
  389.                 get_ouraddress(&ctic->origin,0,0,0,0);
  390.                 fd_origin++;
  391.             }
  392.         }
  393.     }    
  394.     
  395.     /* 1st checks */
  396.     if(!fd_origin)
  397.     {
  398.         logline(2,"Missing 'Origin' field!");
  399.         badtick++;
  400.     }
  401.     if(!fd_from)
  402.     {
  403.         logline(2,"Missing 'From' field!");
  404.         badtick++;
  405.     }
  406.     if(!fd_area)
  407.     {
  408.         logline(2,"Missing 'Area' field!");
  409.         badtick++;
  410.     }
  411.     if(!fd_desc)
  412.     {
  413.         logline(2,"Missing 'Desc' field!");
  414.         badtick++;
  415.     }
  416.     if(!fd_file)
  417.     {
  418.         logline(2,"Missing 'File' field!");
  419.         badtick++;
  420.     }
  421.     
  422.     if(!badtick)
  423.     { /* second checks */
  424.         mylist=get_area(ctic->area);
  425.         if(!mylist)
  426.         {
  427.             logline(2,"Area %s doesn't exist!",ctic->area);
  428.             badtick++;
  429.         }
  430.         else
  431.         { /* got echolist */
  432.             if(stat(ctic->filepath,&mystat))
  433.             {
  434.                 logline(3,"File %s not received!",ctic->filepath);
  435.                 badtick++;
  436.             }
  437.             else /* ok */
  438.             {
  439.                 if(ctic->size)
  440.                 {
  441.                     if(mystat.st_size!=ctic->size)
  442.                     {
  443.                         logline(2,"Bad file size!");
  444.                         badtick++;
  445.                     }    
  446.                 }
  447.                 else
  448.                     ctic->size=mystat.st_size;
  449.                 
  450.                 if(fd_crc)
  451.                 {
  452.                     unsigned long tempcrc;
  453.                     if(crc32file(ctic->filepath,&tempcrc)==BBSOK)
  454.                     {
  455.                         if(ctic->crc!=tempcrc)
  456.                         {
  457.                             logline(2,"Bad CRC on %s!",ctic->filepath);
  458.                             badtick++;
  459.                         }
  460.                     }
  461.                     else
  462.                     {
  463.                         logline(4,"Can't calculate CRC32");
  464.                         badtick++;
  465.                     }
  466.                 }
  467.                 else
  468.                 {
  469.                     if(crc32file(ctic->filepath,&ctic->crc)==BBSFAIL)
  470.                     {
  471.                         logline(4,"Can't calculate CRC-32");
  472.                         badtick++;
  473.                     }
  474.                 }
  475.                 
  476.                 /* check from */
  477.                 mynode=mylist->firstnode;
  478.                 while(mynode)
  479.                 {
  480.                     if(mynode->zone==ctic->from.zone
  481.                          && mynode->net==ctic->from.net
  482.                          && mynode->node==ctic->from.node
  483.                          && mynode->point==ctic->from.point)
  484.                          break;
  485.                     mynode=mynode->next;
  486.                 }
  487.                 if(!mynode)
  488.                 {
  489. /* fixme: do it nicer? */
  490.                     if(tickfile) /* !hatch */
  491.                     {
  492.                         logline(2,"%d:%d/%d.%d is not a subscriber to %s",
  493.                             ctic->from.zone,ctic->from.net,ctic->from.node,ctic->from.point,
  494.                             ctic->area);
  495.                         badtick++;
  496.                     }
  497.                 }
  498.                 
  499.                 if(fd_pw)
  500.                 {
  501.                     
  502.                     shadowpass[0]=0;
  503.                     get_password(shadowpass,ctic->from.zone,ctic->from.net,
  504.                                 ctic->from.node,ctic->from.point);
  505.                     if(strnicmp(shadowpass,ctic->password,7))
  506.                     {
  507.                         logline(2,"Bad password for file %s (%s)",ctic->file,ctic->password);
  508.                         /* badtick++; */
  509.                     }
  510.                 }
  511.             }
  512.         } /* end got echolist */
  513.     }
  514.  
  515.     /* copy the file to area */
  516.     if(!badtick)
  517.     {
  518.         strcpy(buffer,mylist->file);
  519.         strcat(buffer,ctic->file);
  520.     
  521.         if((descf=fopen(buffer,"r"))!=NULL)
  522.         {    
  523.             fclose(descf);
  524.             logline(2,"File %s already exists",buffer);
  525.             badtick++;
  526.         }
  527.         else
  528.         {
  529.             if(copyfile(ctic->filepath,buffer)==BBSOK)
  530.             {
  531.                 logline(1,"Received file %s in area %s from %d:%d/%d.%d via %d:%d/%d.%d",
  532.                         ctic->file,ctic->area,
  533.                         ctic->origin.zone,ctic->origin.net,
  534.                         ctic->origin.node,ctic->origin.point,
  535.                         ctic->from.zone,ctic->from.net,
  536.                         ctic->from.node,ctic->from.point);
  537.                 announce_tic(ctic,mylist->group);
  538.                 if(remove(ctic->filepath))
  539.                     logline(3,"Can't remove %s",ctic->filepath);
  540.                 strcpy(ctic->filepath,buffer);
  541.             
  542.                 sprintf(desctmp,"%s%s",mylist->file,FILESBBS);
  543.                 descf=fopen(desctmp,"a");
  544.                 if(!descf)
  545.                 {
  546.                     logline(4,"Can't open file.bbs!");
  547.                     badtick++;
  548.                 }
  549.                 else
  550.                 {
  551.                     fprintf(descf,"%-12.12s %s\n",ctic->file,ctic->desc);
  552.                     fclose(descf);
  553.                 }
  554.             }    
  555.             else
  556.             {
  557.                 logline(4,"Can't copy %s to %s?",ctic->filepath,buffer);    
  558.                 badtick++;
  559.             }
  560.         }
  561.     }
  562.     
  563.     if(badtick)
  564.     { /* Bad file */
  565.         if(tickfile)
  566.         {
  567.             strcpy(buffer,tickfile);
  568.             strcpy(buffer+strlen(buffer)-4,".BTK");
  569.             ptr=strrchr(buffer,SYSSEPAR);
  570.             if(ptr)
  571.             {
  572.                 logline(3,"Bad TIC file %s renamed to %s",tickfile,ptr?++ptr:buffer);
  573.                 if(rename(tickfile,buffer))
  574.                     logline(3,"Can't rename %s",tickfile);
  575.             }
  576.         }
  577.         else
  578.             logline(1,"Hatch failed");
  579.     }
  580.     else
  581.     { /* We succesfully received the file */
  582.         if(tickfile)
  583.         {
  584.             if(remove(tickfile))
  585.                 logline(3,"Can't delete %s",tickfile);
  586.         }
  587.         
  588.         /* send the file to other nodes */
  589.         mynode=mylist->firstnode;
  590.         while(mynode)
  591.         {
  592.             seen_flag=0;
  593.             /* check seen by */
  594.             for(i=0;i<ctic->seenby_nb;i++)
  595.             {
  596.                 if(ctic->seenby[i].zone==mynode->zone
  597.                         && ctic->seenby[i].net==mynode->net
  598.                         && ctic->seenby[i].node==mynode->node
  599.                         && ctic->seenby[i].point==mynode->point)
  600.                     seen_flag++;
  601.             }
  602.             if(ctic->from.zone==mynode->zone /* do not resend to sender */
  603.                 && ctic->from.net==mynode->net
  604.                 && ctic->from.node==mynode->node
  605.                 && ctic->from.point==mynode->point)
  606.                     seen_flag++;
  607.             if(!seen_flag)
  608.             { /* not seen by */
  609.                 if(ctic->seenby_nb<MAXSEEN)
  610.                 {
  611.                     ctic->seenby[ctic->seenby_nb].zone=mynode->zone;
  612.                     ctic->seenby[ctic->seenby_nb].net=mynode->net;
  613.                     ctic->seenby[ctic->seenby_nb].node=mynode->node;
  614.                     ctic->seenby[ctic->seenby_nb].point=mynode->point;
  615.                     ctic->seenby[ctic->seenby_nb].position=1;
  616.                     ctic->seenby_nb++;
  617.                 }
  618.             }
  619.             mynode=mynode->next;
  620.         }
  621.         for(i=0;i<ctic->seenby_nb;i++)
  622.         {
  623.             if(ctic->seenby[i].position)
  624.             {
  625.                 logline(1,"Sending %s to %d:%d/%d.%d",
  626.                     ctic->file, ctic->seenby[i].zone,
  627.                     ctic->seenby[i].net,
  628.                     ctic->seenby[i].node,
  629.                     ctic->seenby[i].point);
  630.                 send_tic(ctic,ctic->seenby[i].zone,
  631.                     ctic->seenby[i].net,
  632.                     ctic->seenby[i].node,
  633.                     ctic->seenby[i].point);
  634.                 
  635.             }
  636.         }
  637.     }
  638.     free(ctic);
  639. }
  640.  
  641. void send_tic(BTICFILE *tic, int zone, int net, int node, int point)
  642. {
  643.     char ticknm[BBSSTR];
  644.     char outdir[BBSSTR];
  645.     FILE *tfl;
  646.     FILE *outfl;
  647.     FILE *tmpfl;
  648.     FIDONODE ourad;
  649.     char password[BBSSTR];
  650.     char datebuf[BBSSTR];
  651.     unsigned long tickid;
  652.     time_t timer;
  653.     int i,try=100;
  654.     
  655.     get_ouraddress(&ourad,zone,net,node,point);
  656.     tickid=(unsigned long) timenix(NULL);
  657.     
  658.     /* create tickfile */
  659.     while(try>0)
  660.     {
  661.         sprintf(ticknm,"%s%lx.TIC",get_ticktemp(),tickid);
  662.         
  663.         /* test existence */
  664.         tmpfl=fopen(ticknm,"r");
  665.         if(tmpfl)
  666.             fclose(tmpfl);
  667.         else
  668.             break;
  669.             
  670.         try--;
  671.         tickid++;
  672.     }
  673.     
  674.     if(!try)
  675.     {
  676.         logline(4,"Can't find unique ID!");
  677.         return;
  678.     }
  679.     
  680.     tfl=fopen(ticknm,"w");
  681.     if(tfl)
  682.     {
  683.         logline(0,"Creating %s",ticknm);
  684.         /* area */
  685.         fprintf(tfl,"Area %s\n",tic->area);
  686.         /* origin */
  687.         fprintf(tfl,"Origin %d:%d/%d",tic->origin.zone,
  688.             tic->origin.net,tic->origin.node);
  689.         if(tic->origin.point)
  690.             fprintf(tfl,".%d",tic->origin.point);
  691.         fprintf(tfl,"\n");
  692.         /* from */
  693.         fprintf(tfl,"From %d:%d/%d",ourad.zone,ourad.net,ourad.node);
  694.         if(ourad.point)
  695.             fprintf(tfl,".%d",ourad.point);
  696.         fprintf(tfl,"\n");
  697.         /* file */
  698.         fprintf(tfl,"File %s\n",tic->file);
  699.         /* desc */
  700.         fprintf(tfl,"Desc %s\n",tic->desc);
  701.         /* crc */
  702.         fprintf(tfl,"CRC %lx\n",tic->crc);
  703.         /* (c) */
  704.         fprintf(tfl,"Created by %s v. %s\n",LAZYNAME,LAZYVERS);
  705.         /* pass */
  706.         for(i=0;i<tic->pass_nb;i++)
  707.         {
  708.             fprintf(tfl,"%s\n",tic->pass[i]);
  709.         }
  710.         /* path */
  711.         time(&timer);
  712.         strftime(datebuf,BBSSTR,"%a %b %d %H:%M:%S %Y %Z GMT",gmtime(&timer));
  713.         fprintf(tfl,"Path %d:%d/%d",ourad.zone,ourad.net,ourad.node);
  714.         if(ourad.point)
  715.             fprintf(tfl,".%d",ourad.point);
  716.         fprintf(tfl," %lu %s\n",tickid,datebuf);
  717.         /* seenby */
  718.         for(i=0;i<tic->seenby_nb;i++)
  719.         {
  720.             fprintf(tfl,"Seenby %d:%d/%d",tic->seenby[i].zone,
  721.                 tic->seenby[i].net,tic->seenby[i].node);
  722.             if(tic->seenby[i].point)
  723.                 fprintf(tfl,".%d",tic->seenby[i].point);
  724.             fprintf(tfl,"\n");
  725.         }
  726.         /* password */
  727.         get_password(password,zone,net,node,point);
  728.         if(*password)
  729.         {
  730.             fprintf(tfl,"Pw %s\n",password);
  731.         }
  732.         fclose(tfl);
  733.     
  734.     
  735.         /* append to outbound directory */
  736.         if(get_out_fname(outdir,zone,net,node,point)==BBSOK)
  737.         {
  738.             outfl=fopen(outdir,"a");
  739.             if(outfl)
  740.             {
  741.                 fprintf(outfl,"%s\n",tic->filepath);
  742.                 fprintf(outfl,".%s\n",ticknm);
  743.                 fclose(outfl);
  744.             }
  745.         }
  746.         else
  747.             logline(4,"Can't open %s",outdir);
  748.     }
  749. }
  750.  
  751. /**/